#include"mystdio.h"
#include<fcntl.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<stdlib.h>
void my_fclose(myFILE*fp)
{
    my_fflush(fp);
    close(fp->fileno);
    free(fp);
}

myFILE* my_fopen(const char* pathname,const char* mode)
{
    int flag =0;
    if(strcmp(mode,"r")==0)
    {
        flag = O_RDONLY;
    }
    else if(strcmp(mode,"w")==0)
    {
        flag = O_WRONLY | O_CREAT | O_TRUNC;
    }else if (strcmp(mode,"a")==0)
    {
        flag = O_WRONLY |O_CREAT| O_APPEND;
    }else{
        return NULL;
    }

    int fd = -1;
    if(flag & O_WRONLY)
    {
        fd = open(pathname,flag,0666);
    }
    else
    {
        fd = open(pathname,flag);    
    }
    if(fd==-1)
    {
        perror("open file fail!");
        return NULL;
    }
    myFILE* fp = (myFILE*)malloc(sizeof(myFILE));
    if(fp==NULL)
    {
        perror("malloc fail!");
        return NULL;
    }
    fp->fileno = fd;
    fp->cap = SIZE;
    fp->flush_mode = LINE_FLUSH;
   // printf("\nflush_mode:%d\n",fp->flush_mode);
    fp->pos =0;

    return fp;
}



int my_fwrite(myFILE*fp,char* str,size_t size)
{
    // first copy the data to buffer
    memcpy(fp->outbuffer+fp->pos,str,size);
    fp->pos += size;
    // printf("flush-mode:%d\n",fp->flush_mode);
    // printf("line-flush:%d",LINE_FLUSH);
    // judge whether to flush,and the default flush-mode is line-flush
    if((fp->flush_mode) & LINE_FLUSH)
    {
        if(fp->outbuffer[fp->pos-1]=='\n')
        {
            // flush the buffer to file
            printf("LINE");
            my_fflush(fp);
        }
    }
    else if (fp->flush_mode & FULL_FLUSH)
    {
        if(fp->pos == fp->cap)
        {
            printf("FULL");
            my_fflush(fp);
        }
    }
    // for this branch,the flush-mode is flush immediately.
    else
    {
        printf("\nINTERMEDiate\n");
        my_fflush(fp);
    }
    return size;
}

int my_fread(myFILE*fp, char* str,size_t size)
{
    return read(fp->fileno,str,size);
}

void my_fflush(myFILE*fp)
{
    if(fp->pos == 0) return;
    write(fp->fileno,fp->outbuffer,fp->pos); // copy the data to the OS kernal
    fp->pos = 0; 
}
